
#ifndef  HELPER_SCOPE_SCOPEGUARDWRAPPER_H
#define  HELPER_SCOPE_SCOPEGUARDWRAPPER_H

#include <memory>
#include "ScopableAdapter.h"
#include "ScopeGuard.h"

namespace helper {
namespace scope {

template<typename T>
class ScopeGuardWrapper {
public:
    template<typename fnEnter, typename fnExit>
    ScopeGuardWrapper(T & t, const fnEnter & enter, const fnExit & exit)
    : scopable(new ScopableAdapter<T>(enter, exit))
    , scopeGuard(t, *scopable)
    {
    }
private:
    std::unique_ptr<IScopable<T>> scopable;
    ScopeGuard<T> scopeGuard;
};

template<>
class ScopeGuardWrapper<void> {
public:
    template<typename fnEnter, typename fnExit>
    ScopeGuardWrapper(const fnEnter & enter, const fnExit & exit)
    : scopable(new ScopableAdapter<void>(enter, exit))
    , scopeGuard(*scopable)
    {
    }
private:
    std::unique_ptr<IScopable<void>> scopable;
    ScopeGuard<void> scopeGuard;
};

}// end of namespace scope
}// end of namespace helper

#endif   /* HELPER_SCOPE_SCOPEGUARDWRAPPER_H */
